perm filename MEMMF.TXT[MF,DEK] blob
sn#762757 filedate 1984-07-27 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00007 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 On July 26--27, 1984 I made a version of MF that was designed to help spot
C00004 00003 I changed TRAP.MF by ending as follows: [if TRAP has changed, suitable
C00006 00004 @x special patches for memory allocation (follows "Eliminating addition/sub...")
C00008 00005 @x changes to dump/undump for the new memory stuff
C00009 00006 @x new debugging feature to write out a file of free locations (#11 0 16 0)
C00010 00007 % new stuff at the end of the very last page of the change file
C00011 ENDMK
C⊗;
On July 26--27, 1984 I made a version of MF that was designed to help spot
"memory wastage" errors.
(This was similar to what I did with TeX, see MEMTEX.TXT[tex,dek].)
Basically, the getavail and getnode routines were changed so that they
never recycled any nodes. Then the nodes that were not freed at the
end of the program were erroneous; and a second pass could be used to
identify the source of the erroneous nodes.
The following pages of this file show the additions I made to the
ordinary change file, in order to make MEMMF. Actually I made these
changes to BUGMF.CH; the mem_max was increased to 30000 and hi_mem_base
to 15000, besides the other changes cited.
(To create the FREE.TMP file, I used TeX's debugger, saying
#11 0 16 0
where 16 was a new option that writes that new file. When FREE.TMP
exists, INIMF (but not with a preloaded format) will load it.)
I changed TRAP.MF by ending as follows: [if TRAP has changed, suitable
modifications should be made]
@x
bye endtext
@y
endgroup endfor
fi fi fi; save <<,foo,bar,x,y,alpha,beta,s,q,e,/*\,\*/,w,pp,qq,//,!,p,inimf,',
↑,~,_aa__,**,***,++,texts,a,b,c,f,g,clear,dp,_,`','`,xx,yy;
errorstopmode; showstats; ddt;
@z
To run: First delete FREE.TMP.
Then run BUGMF and \input trap (as usual).
Then run BUGMF and &trap trap.mem.
When it stops with showstats, type D and then 11 0 16 0 -1 to the debugger.
Then run BUGMF and set breakpoints in get_avail and get_node;
\input trap and/or &trap trap.mem will stop when unrecycled nodes
are first allocated.
@x special patches for memory allocation (follows "Eliminating addition/sub...")
get_avail←p;
@y
if not was_free[p] then
begin @{@/
'*************breakpoint*************';@/
'***********for**debugging***********'@};
end;
get_avail←p;
@z
@x
begin link(#)←avail; avail←#;
@y
begin link(#)←vail; vail←#;
@z
@x
get_node←r;
@y
if not was_free[r] then
begin @{@/
'*************breakpoint*************';@/
'***********for**debugging***********'@};
end;
get_node←r;
@z
@x
while is_empty(q) do @<Merge node |p| with node |q|@>;
@y
while false do @<Merge node |p| with node |q|@>;
@z
@x
p←avail; q←null; clobbered←false;
@y
p←vail; q←null; clobbered←false;
@z
@x changes to dump/undump for the new memory stuff
dump_int(mem_end); dump_int(avail);
for k←p to mem_end do dump_wd(mem[k]);
x←x+mem_end+1-p;
p←avail;
@y
dump_int(mem_end); dump_int(vail);
for k←p to mem_end do dump_wd(mem[k]);
x←x+mem_end+1-p;
p←vail;
@z
@x
undump(null)(mem_end)(avail);
@y
undump(null)(mem_end)(vail);
@z
@x new debugging feature to write out a file of free locations (#11 0 16 0)
15: panicking←not panicking;
@y
15: panicking←not panicking;
16: begin rewrite(free_file,'FREE.TMP');
for k←0 to mem_max do
begin free_file↑←free[k]; put(free_file);
end;
end;
@z
% new stuff at the end of the very last page of the change file
@ And still still more finally: Freed nodes go into |vail| instead of
|avail|, so there is no recycling. An auxiliary |free_file| is used to
record memory usage.
@<Glob...@>=
@!vail:pointer;
@!free_file:file of boolean;
@ @<Set init...@>=
reset(free_file,'FREE.TMP','/O');
if not eof(free_file) then
begin for k←0 to mem_max do
begin was_free[k]←free_file↑; get(free_file);
end;
end;
@z